package com.voja.mrvica2;

import java.util.ArrayList;
import java.util.Calendar;

import com.voja.mrvica2.adapter.EntryAdapter;
import com.voja.mrvica2.adapter.MenuAdapter;
import com.voja.mrvica2.db.EntryGroup;
import com.voja.mrvica2.db.EntryItem;
import com.voja.mrvica2.fragment.DetailsFragment;
import com.voja.mrvica2.fragment.MiddleFragment;
import com.voja.mrvica2.listener.MenuItemClickListener;
import com.voja.mrvica2.rss.RSS;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ShareActionProvider;
import android.widget.Toast;


public class Index extends Activity {
    public static Context context;
    
    public DrawerLayout          drawer;
    public ListView              drawerMenu;
    public FrameLayout           detailsView;
    public ActionBarDrawerToggle drawerToggler;
    
    public FrameLayout           middleView;
    public LinearLayout          throbber;

    public CharSequence          drawerTitle;
    public CharSequence          appTitle;
    
    public static Resources        res;
    public static ArrayList<Entry> categories;
    public static ArrayList<Entry> items;
    public static int              categoryId;
    public static int              categoryPosition;
    
    private String server, actionCategories, actionItems;
    
    public long backKeyTS = 0;
    public long backKeyTO = 2000;
    
    public static int page = 1;
    public boolean inDetails = false;
    
    public static MiddleFragment  middleFragment;
    public static DetailsFragment detailsFragment;
    public static MenuItem        share;
    
    public Animator middleAnimator, detailsAnimator;
    
    public EntryGroup entryGroup;
    public EntryItem  entryItem;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.index);

        context = getApplicationContext();
        categoryId       = -1;
        categoryPosition = -1;
        categories       = new ArrayList<Entry>();
        
        res = getResources();
        server           = res.getString(R.string.SERVER);
        actionCategories = res.getString(R.string.ACTION_CATEGORIES);
        actionItems      = res.getString(R.string.ACTION_CATEGORY_LIST);
        
        appTitle    = drawerTitle = getTitle();
        drawer      = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawerMenu  = (ListView)     findViewById(R.id.menu_drawer);
        throbber    = (LinearLayout) findViewById(R.id.throbber);
        middleView  = (FrameLayout)  findViewById(R.id.middle_frame);
        detailsView = (FrameLayout)  findViewById(R.id.details_frame);
        
        entryGroup = new EntryGroup(context);
        entryItem  = new EntryItem(context);
        
        setFrameSize(middleView);
        setFrameSize(detailsView);
        
        middleAnimator  = new Animator(middleView);
        detailsAnimator = new Animator(detailsView);

        // set home-button enabled
        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);
        
        loadMenu();
    }
    
    public void setFrameSize(FrameLayout frame) {
        DrawerLayout.LayoutParams p = (DrawerLayout.LayoutParams)frame.getLayoutParams();
        p.width = App.displayWidth;
        frame.setLayoutParams(p);
    }
    
    public void loadMenu() {
        ArrayList<Entry> groups = entryGroup.get();
        
        if (entryGroup.expired() || groups.size() < 1) {
            new RSS(this, server + actionCategories, "beforeLoadMenu", "loadedAndSaveMenu");
        } else {
            loadedMenu(groups);
        }
    }
    
    public void beforeLoadMenu() {
        findViewById(R.id.throbber).setVisibility(View.VISIBLE);
    }
    
    public void loadedAndSaveMenu(ArrayList<Entry> data) {
        entryGroup.save(data);
        loadedMenu(data);
    }
    
    public void loadedMenu(ArrayList<Entry> data) {
        findViewById(R.id.throbber).setVisibility(View.GONE);
        
        categories = data;
        initDrawer();
        selectMenuItem(0);
    }
    
    public void loadItems() {
        ArrayList<Entry> countries = entryItem.get(categoryId, page);
        
        if (entryItem.expired(categoryId) || countries.size() < 1) {
            new RSS(
                this, 
                server + String.format(actionItems, categoryId, page), 
                "beforeLoadItems", 
                "completedAndSaveLoadItems"
            );
        } else {
            completedLoadItems(countries);
        }
    }
    
    public void beforeLoadItems() {
    }
    
    public void completedAndSaveLoadItems(ArrayList<Entry> items) {
        if (items.size() > 0) {
            entryItem.itemsPerPage = items.size();
        }
        entryItem.save(categoryId, items);
        completedLoadItems(items);
    }
    
    public void completedLoadItems(ArrayList<Entry> items) {
        if (page > 1) {
            EntryAdapter adapter = (EntryAdapter)middleFragment.getListAdapter();
            EntryAdapter.loading = false;
            
            adapter.removeLast();
            if (items.size() > 0) {
                for (int i=0; i<items.size(); i++) {
                    adapter.add(items.get(i));
                }
            } else {
                EntryAdapter.loaded = true;
            }
        } else {
            drawerMenu.setItemChecked(categoryPosition, true);
            setTitle(categories.get(categoryPosition).getTitle());
            drawer.closeDrawer(drawerMenu);
            
            Index.items = items;
            middleFragment = new MiddleFragment();
            middleFragment.setParams(items, this);
            setMiddleFrameContents();
        }
    }
    
    private void initDrawer() {
        // drawer
        drawer.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
        
        // drawerMenu
        drawerMenu.setAdapter(new MenuAdapter(this, R.layout.menu_item, categories));
        drawerMenu.setOnItemClickListener(new MenuItemClickListener(this));
        drawerMenu.setBackgroundColor(res.getColor(R.color.menuBackground));

        // set drawer toggler
        drawerToggler = new DrawerToggle(this);
        drawer.setDrawerListener(drawerToggler);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.item, menu);
        
        // Share Option
        Index.share = menu.findItem(R.id.menuShare);
        Index.shareHide();
        
        return super.onCreateOptionsMenu(menu);
    }
    
    public void setShareProvider() {
        ShareActionProvider shareProvider = (ShareActionProvider)share.getActionProvider();
        shareProvider.setShareIntent(getShareIntent());
    }
    
    public static void shareShow() {
        if (Index.share != null) {
            Index.share.setVisible(true);
        }
    }
    
    public static void shareHide() {
        if (Index.share != null) {
            Index.share.setVisible(false);
        }
    }
    
    public Intent getShareIntent() {
        Intent i = new Intent(Intent.ACTION_SEND);
        i.setType("text/plain");
        
        if (Index.detailsFragment != null) {
            Entry e = detailsFragment.getEntry();
            i.putExtra(Intent.EXTRA_SUBJECT, e.getTitle());
            i.putExtra(Intent.EXTRA_TEXT, e.getLink());
        } else {
            App.alert("No Details.");
        }
        return i;

    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        return super.onPrepareOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        
        if (inDetails) {
            hideDetails();
        } else if(drawerToggler != null) {
            if (drawerToggler.onOptionsItemSelected(item)) {
                return true;
            }
        }
        
        return super.onOptionsItemSelected(item);
    }
    
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        boolean ret = true;
        
        switch (keyCode) {
        case KeyEvent.KEYCODE_MENU:
            if (categories.size() > 0) {
                if (drawer.isDrawerVisible(drawerMenu)) {
                    drawer.closeDrawer(drawerMenu);
                } else {
                    drawer.openDrawer(drawerMenu);
                }
            }
            break;
            
        case KeyEvent.KEYCODE_BACK:
            if (! drawer.isDrawerOpen(drawerMenu)) {
                
                if (inDetails) {
                    hideDetails();
                } else {
                    long now = Calendar.getInstance().getTimeInMillis();
                    
                    if (backKeyTS>0 && ((now - backKeyTS) < backKeyTO)) {
                        ret = super.onKeyDown(keyCode, event);
                    } else {
                        backKeyTS = now;
                        Toast.makeText(this, res.getString(R.string.exitConfirm), Toast.LENGTH_SHORT).show();
                        ret = true;
                    }
                }
            } else {
                ret = super.onKeyDown(keyCode, event);
            }
            
            break;
            
        default:
            ret = super.onKeyDown(keyCode, event);
        }
        
        return ret;
    }
    
    public void showDetails() {
        middleAnimator.animate(0);
        detailsAnimator.animate(1);
        shareShow();
        inDetails = true;
    }
    
    public void hideDetails() {
        middleAnimator.animate(1);
        detailsAnimator.animate(0);
        shareHide();
        inDetails = false;
    }

    public void selectMenuItem(int position) {
        if (position == categoryPosition) {
            drawer.closeDrawer(drawerMenu);
        } else {
            if (categories.size() < 1) {
                return;
            }
            
            categoryId = categories.get(position).getId();
            categoryPosition = position;
            page = 1;
            if (middleFragment != null) {
                EntryAdapter adapter = (EntryAdapter)middleFragment.getListAdapter();
                if (adapter != null) {
                    EntryAdapter.loaded  = false;
                    EntryAdapter.loading = false;
                }
            }
            
            if (inDetails) {
                hideDetails();
            }
            
            showMenuThrobber(position);
            loadItems();
        }
    }
    
    public void setMiddleFrameContents() {
        getFragmentManager().beginTransaction()
                            .replace(R.id.middle_frame, middleFragment)
                            .commit();
    }

    @Override
    public void setTitle(CharSequence title) {
        appTitle = title;
        getActionBar().setTitle(appTitle);
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        
        if (drawerToggler != null) {
            drawerToggler.syncState();
        }
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
    }
    
    public void showMenuThrobber(int position) {
        View v = getMenuChildAt(position);
        if (v != null) {
            v.findViewById(R.id.throbber).setVisibility(View.VISIBLE);
        }
    }
    
    public void hideMenuThrobber(int position) {
        View v = getMenuChildAt(position);
        if (v != null) {
            v.findViewById(R.id.throbber).setVisibility(View.GONE);
        }
    }
    
    private View getMenuChildAt(int position) {
        int firstPosition = drawerMenu.getFirstVisiblePosition();
        int childPosition = position - firstPosition;
        
        View v = null;
        if (childPosition > 0 && childPosition < drawerMenu.getChildCount()) {
            v = drawerMenu.getChildAt(childPosition);
        }
        
        return v;
    }
}
